package com.yangrong.thread.chapter8;

import java.util.stream.Stream;

/**
 * 错误示例，多个生产者、消费者利用wait、notify线程间通信造成假死
 * 
 * @author YangRong
 * @date 2020年5月27日
 */
public class ProduceConsumerVersion3 {

	private int i = 0;

	private final Object LOCK = new Object();

	private volatile boolean isProduced = false;

	public void produce() {
		synchronized (LOCK) {
			if (isProduced) {
				try {
					LOCK.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {
				i++;
				System.out.println("P->" + i);
				isProduced = true;
				LOCK.notify();
			}
		}
	}

	public void consume() {
		synchronized (LOCK) {
			if (isProduced) {
				System.out.println("C->" + i);
				isProduced = false;
				LOCK.notify();
			} else {
				try {
					LOCK.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public static void main(String[] args) {
		ProduceConsumerVersion3 pc = new ProduceConsumerVersion3();

		Stream.of("P1", "P2").forEach(n -> new Thread(n) {
			public void run() {
				while (true) {
					pc.produce();
				}
			};
		}.start());

		Stream.of("C1", "C2").forEach(n -> new Thread(n) {
			public void run() {
				while (true) {
					pc.consume();
				}
			};
		}.start());
	}

}
